package Test;

import static org.junit.Assert.*;

import interfaces.TableFile;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import Calculate.ByteCalc;
import Script.JTableFile;

public class JTableFileTest {
	private JTableFile table;
	private JTableFile tableLength;
	private String separator;
	private String endLine = "<LINE>";
	
	@Before
	public void setup() {
		File tableFile = new File("TestFiles/ff3_table.tbl");
		File tableFileLength = 
				new File("TestFiles/testTableFiles/table_length_test.tbl");
		
		/* Create table file object. */
		try {
			table = new JTableFile(tableFile);
			tableLength = new JTableFile(tableFileLength);
			separator = System.getProperty("line.separator");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@Test
	public void insertedItemCanBeRetrievedInDumpingTable() throws IOException {
		byte[] t2 = table.getBytes(" t");
		byte[] t = ByteCalc.longToByteArray(129);
		t = ByteCalc.subArray(t, t.length - t2.length, t.length);
		assertTrue(Arrays.equals(t, t2));
	}
	
	@Test
	public void insertedItemCanBeRetrievedInInsertTable() throws IOException {
		byte[] t = ByteCalc.longToByteArray(129);
		t = ByteCalc.subArray(t, t.length - 1, t.length);
		
		assertEquals(table.getString(t), " t");
	}
	
	@Test
	public void newlineCharsCanBeStoredAndRetrievedWithHex() throws IOException {
		byte[] t = ByteCalc.longToByteArray(19);
		t = ByteCalc.subArray(t, t.length - 1, t.length);
		
		assertEquals(table.getString(t), endLine + separator);
	}
	
	@Test
	public void newlineCharsCanBeStoredAndRetrievedWithString() throws IOException {
		byte[] t = ByteCalc.longToByteArray(19);
		t = ByteCalc.subArray(t, t.length - 1, t.length);
		
		assertEquals(endLine + separator, table.getString(t));
	}
	
	@Test
	public void endCharsCanBeStoredAndRetrievedWithHex() throws IOException {
		byte[] t = ByteCalc.longToByteArray(0);
		t = ByteCalc.subArray(t, t.length - 1, t.length);
		
		assertEquals(table.getString(t), "<END>" + separator);
	}
	
	@Test
	public void endCharsCanBeStoredAndRetrievedWithString() throws IOException {
		byte[] t = ByteCalc.longToByteArray(0);
		t = ByteCalc.subArray(t, t.length - 1, t.length);
		
		assertEquals("<END>" + separator, table.getString(t));
	}
	
	@Test
	public void multipleSpecialCharsReturnOnlyTheLastInserted() throws IOException {
		byte[] t = ByteCalc.longToByteArray(19);
		t = ByteCalc.subArray(t, t.length - 1, t.length);
		
		assertTrue(Arrays.equals(table.getBytes(endLine), t));
	}
	
	@Test
	/**
	 * Tests to retrieve &h2822, AJJA.
	 */
	public void canStoreHexLongerThenOneByte() throws IOException {
		byte[] t = ByteCalc.longToByteArray(10274);
		t = ByteCalc.subArray(t, t.length - 2, t.length);
		
		assertEquals(table.getString(t), "AJJA");
	}
	
	/**
	 * Tests to retrieve &h1122334455667788, 8tta.
	 * 
	 * 8 bytes in size.
	 */
	@Test
	public void canStoreMaxLengthBytes() {
		long num = Long.parseLong("1122334455667788", 16);
		byte[] t = ByteCalc.longToByteArray(num);
		t = ByteCalc.subArray(t, t.length - 8, t.length);
		
		assertEquals(table.getString(t), "8tta");
	}
	
	public void canHandleLargeHexValue() {
		//TODO Handle the exception that occurs when a large hex is specified. 9911223344556677
	}
	
	@Test
	public void canMeasureLongestHexEntryInBytes() {
		assertTrue(tableLength.getHexMaxLength() == 3);
		
	}
	
	@Test
	public void canMeasureLongestTextEntryInBytes() {
		assertTrue(tableLength.getTextMaxLength() == 4);
		
	}
	
	@Test
	public void includesTheTextSizeOfSpecialCharactersWhenTheyAreLongerThanRegularEntries() throws IOException {
		File tableFile = new File("TestFiles/testTableFiles/table1.tbl");
		TableFile table = new JTableFile(tableFile);
		
		assertEquals(table.getTextMaxLength(), 7);
	}
	
	@Test
	public void includesTheByteSizeOfSpecialCharactersWhenTheyAreLongerThanRegularEntries() throws IOException {
		File tableFile = new File("TestFiles/testTableFiles/table1.tbl");
		TableFile table = new JTableFile(tableFile);
		
		assertEquals(table.getHexMaxLength(), 2);
	}
}
